package web

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/url"
	"strconv"
)

type Context struct {
	Req        *http.Request
	Resp       http.ResponseWriter
	PathParams map[string]string

	// 缓存query参数
	QueryValues url.Values
}
type StringValue struct {
	value string
	err   error
}

func (c *Context) QueryValue(key string) StringValue {
	if c.QueryValues == nil {
		c.QueryValues = c.Req.URL.Query()
	}
	values, ok := c.QueryValues[key]
	if !ok {
		return StringValue{
			err: errors.New("web: query is nil"),
		}
	}
	//因为是切片只取出第一个
	return StringValue{
		value: values[0],
	}
	// 用户区别不出来是真的有值，但是值恰好是空字符串
	// 还是没有值
	// return c.queryValues.Get(key), nil
}
func (c *Context) PathValue(key string) StringValue {
	value, ok := c.PathParams[key]
	if !ok {
		return StringValue{err: errors.New("web: path is nil")}
	}
	return StringValue{
		value: value,
	}
}

// FromValue form表单解析
func (c *Context) FromValue(key string) StringValue {
	err := c.Req.ParseForm()
	if err != nil {
		return StringValue{
			err: errors.New("web: form 解析出错"),
		}
	}
	value := c.Req.FormValue(key)
	return StringValue{value: value}
}

// BindJson 绑定json
func (c *Context) BindJson(key any) error {
	// body为空
	if c.Req.Body == nil {
		return errors.New("web: body is nil")
	}
	// useNumber => 数字就是用 Number 来表示
	// 否则默认是 float64
	// if jsonUseNumber {
	// 	decoder.UseNumber()
	// }

	// 如果要是有一个未知的字段，就会报错
	// 比如说你 User 只有 Name 和 Email 两个字段
	// JSON 里面额外多了一个 Age 字段，那么就会报错
	// decoder.DisallowUnknownFields()
	decoder := json.NewDecoder(c.Req.Body)
	return decoder.Decode(key)
}

// AsInt64 链式调用,可以将上面参数解析转成int64
func (s *StringValue) AsInt64() (int64, error) {
	if s.err != nil {
		return 0, s.err
	}
	return strconv.ParseInt(s.value, 10, 64)
}
